﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using WatiN.Core;
//using WatiN.Core.Native.InternetExplorer;
using SHDocVw;

namespace Mail2Portfolio
{
    public partial class MainForm : System.Windows.Forms.Form
    {
        public MainForm()
        {
            InitializeComponent();
        }


        private void MainForm_Shown(object sender, EventArgs e)
        {
            OpenPortfolio();
        }

        /*public delegate void myDelegate();
        private void UnRedBrowser()
        {
            if (browser_main.InvokeRequired)
            {
                myDelegate my = new myDelegate(UnRedBrowser);
                this.Invoke(my, new object[] { });
            }
            else
            {
                tabPage1.BackColor = Color.Transparent;
            }
        }*/

        private void OpenPortfolio()
        {
            browser_main.ScriptErrorsSuppressed = true;
            browser_main.GoBack(); // a trick to init it (http://bytes.com/topic/c-sharp/answers/691393-activexinstance-null-after-initializecomponent)

            Start_Trans_Processor();
            Thread.Sleep(1000);
            AddTrans_via_Queue(new Transaction { Symbol = "hello!" }); // means "open the portfolio"
            //BrowserAction(ie => ie.GoTo("https://www.google.com/finance/portfolio"));
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            AddTrans_via_Queue(new Transaction { Symbol = "goodbye!" });
        }

        /*private void BrowserAction(Action<WebBrowserIE> codeBlock)
        {
            var ie = new WebBrowserIE(browser_main);
            var thread = new Thread(() =>
            {
                try
                {
                    codeBlock(ie);
                    ie.Dispose();
                }
                catch (Exception)
                {
                    // ignore
                }
            });
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            #region some earlier try
            //browser_main.GoBack();
            //var thread = new Thread(() =>
            //{
            //    Settings.AutoStartDialogWatcher = false;

            //    var ie = new IE(browser_main.ActiveXInstance);
            //    //var ie = new IE(new ProxyForIWebBrowser2InterfaceToWorkaroundHWNDBugs((IWebBrowser2)browser_main.ActiveXInstance, browser_main.Handle));

            //    ((System.Windows.Forms.WebBrowser)browser_main).ScriptErrorsSuppressed = true;
                
            //    ie.GoTo("https://www.google.com/finance/portfolio");
            //    //ie.TextField(Find.ByName("q")).TypeTextQuickly("AMD is cheap now");
            //    //ie.Button(Find.ByName("btnG")).Click();
                
            //    FocusBrowser();
            //});
            //thread.SetApartmentState(ApartmentState.STA);
            //thread.Start();
            #endregion
        }*/

        private void btnAddToPortfolio_Click(object sender, EventArgs e)
        {
            var trans = new Transaction
            {
                Symbol = txtSymbol.Text,
                Buy = radioBuy.Checked,
                Time = DateTime.Today,
                Amount = (int)numAmount.Value,
                Price = numPrice.Value,
                Commission = 10,
                Notes = "just did it",
            };

            AddTrans_via_Queue(trans);
        }

        /*public void AddTrans(Transaction trans)
        {
            BrowserAction(ie =>
            {
                ie.TextField(Find.ById("add_symbols")).TypeTextQuickly(trans.Symbol);
                ie.Image(Find.ByClass("plus")).Click();
                ie.SelectList(Find.ById("add_ttype")).Option(trans.Buy ? "Buy" : "Sell").SelectNoWait();
                ie.TextField(Find.ById("add_date")).TypeTextQuickly(trans.Time.ToShortDateString());
                ie.TextField(Find.ById("add_shares")).TypeTextQuickly(trans.Amount.ToString());
                ie.TextField(Find.ById("add_price")).TypeTextQuickly(trans.Price.ToString());
                ie.TextField(Find.ById("add_commission")).TypeTextQuickly(trans.Commission.ToString());
                ie.TextField(Find.ById("add_notes")).TypeTextQuickly(trans.Notes);

                ie.Button(Find.ById("addstock")).Click();
            });
        }*/

        static readonly object queueLock = new object();
        ConcurrentQueue<Transaction> queue = null;

        public void AddTrans_via_Queue(Transaction trans)
        {
            lock (queueLock)
            {
                queue.Enqueue(trans);
                Monitor.Pulse(queueLock);
            }
        }

        void Start_Trans_Processor()
        {
            queue = new ConcurrentQueue<Transaction>();

            var ie = new WebBrowserIE(browser_main);
            var thread = new Thread(() =>
            {
                Transaction trans = null;
                while (true)
                {
                    lock (queueLock)
                    {
                        if (!queue.TryDequeue(out trans))
                        {
                            // No object to dequeue, waiting...
                            // Threads will wait here and only one will be released when .Pulse()d
                            Monitor.Wait(queueLock);
                            queue.TryDequeue(out trans);
                        }
                        if (trans != null)
                        {
                            // processing queue
                            if (trans.Symbol == "goodbye!")
                                break;
                            if (trans.Symbol == "hello!")
                                ie.GoTo("https://www.google.com/finance/portfolio");
                            else
                            {
                                ie.TextField(Find.ById("add_symbols")).TypeTextQuickly(trans.Symbol);
                                ie.Image(Find.ByClass("plus")).Click();
                                ie.SelectList(Find.ById("add_ttype")).Option(trans.Buy ? "Buy" : "Sell").SelectNoWait();
                                ie.TextField(Find.ById("add_date")).TypeTextQuickly(trans.Time.ToShortDateString());
                                ie.TextField(Find.ById("add_shares")).TypeTextQuickly(trans.Amount.ToString());
                                ie.TextField(Find.ById("add_price")).TypeTextQuickly(trans.Price.ToString());
                                ie.TextField(Find.ById("add_commission")).TypeTextQuickly(trans.Commission.ToString());
                                ie.TextField(Find.ById("add_notes")).TypeTextQuickly(trans.Notes);

                                ie.Button(Find.ById("addstock")).Click();
                            }
                        }
                    }
                }
            });
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        private void btnQueueTest_Click(object sender, EventArgs e)
        {
            for (int i = 1; i <= 5; i++)
            {
                string sym = "GOOG";
                if (i == 1)
                    sym = "FB";
                if (i == 2)
                    sym = "CSCO";
                if (i == 3)
                    sym = "BIDU";
                if (i == 4)
                    sym = "ZNGA";
                if (i == 5)
                    sym = "SIRI";
                var trans = new Transaction
                {
                    Symbol = sym,
                    Buy = true,
                    Time = DateTime.Today,
                    Amount = i * 100,
                    Price = 12.34M,
                    Commission = 10,
                    Notes = "just did it",
                };

                AddTrans_via_Queue(trans);
            }
            btnQueueTest.Text = "all sent!";
            btnQueueTest.Enabled = false;
        }
    }

    static class Helpers
    {
        public static void TypeTextQuickly(this TextField textField, string text)
        {
            // http://blog.dbtracer.org/2010/08/05/speed-up-typing-text-with-watin/
            textField.SetAttributeValue("value", text);
        }
    }
}
